<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs"
        :key="item.id">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="val in item.values"
                  :key="val.name">
          <img v-if="val.picture"
               :class="{
              selected: val.name === item.values.selected,
              disabled: val.disabled
            }"
               :src="val.picture"
               :title="val.name"
               @click="changeselected(item.values, val)" />
          <span v-else
                :class="{
              selected: val.name === item.values.selected,
              disabled: val.disabled
            }"
                @click="changeselected(item.values, val)">{{ val.name }}
          </span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import powerset from '@/vender/power-set'
// 分隔符
const spliter = '★'
// 得到路径字典
const getPathMap = (skus) => {
  // 路径字典
  const pathmap = {}
  skus.forEach((item) => {
    // 筛选有效sku，即库存大于0
    if (item.inventory > 0) {
      // 将key值组合成数组
      const valuearr = item.specs.map((val) => {
        return val.valueName
      })
      // 根据组合的数组和power-set算法得出子集
      const powersetarr = powerset(valuearr)
      // console.log(powersetarr)
      // 生成路径字典
      powersetarr.forEach((arr) => {
        const str = arr.join(spliter)
        if (pathmap[str]) {
          // 已经存在
          pathmap[str].push(item.id)
        } else {
          pathmap[str] = [item.id]
        }
      })
    }
  })
  return pathmap
}
// 获取当前选中的数组
const getcurrentsku = (specs) => {
  const changearr = []
  specs.forEach((item) => {
    changearr.push(item.values.selected ? item.values.selected : undefined)
  })
  return changearr
}
// 更新按钮禁用状态
const changebtstatu = (specs, pathmap) => {
  // 将每一个属性组合后去字典中查找
  specs.forEach((item, index) => {
    // 选中的组合
    const changearr = getcurrentsku(specs)
    item.values.forEach((val) => {
      // 如果选中了就不需要判断
      if (changearr[index] === val.name) {
        return
      }
      changearr[index] = val.name
      const key = changearr.filter((value) => value).join(spliter)
      val.disabled = !pathmap[key]
    })
  })
}
// 默认选中
const initDefaultSelected = (goods, skuId) => {
  // 1. 找出sku的信息
  // 2. 遍历每一个按钮，按钮的值和sku记录的值相同，就选中。
  const sku = goods.skus.find((sku) => sku.id === skuId)
  goods.specs.forEach((item, i) => {
    const val = item.values.find((val) => val.name === sku.specs[i].valueName)
    item.values.selected = val.name
  })
}

export default {
  name: 'GoodsSku',
  props: {
    goods: {
      type: Object,
      default: () => { }
    },
    skuId: {
      type: String,
      default: ''
    }
  },
  setup (props, { emit }) {
    // 初始化sku
    if (props.skuId) {
      initDefaultSelected(props.goods, props.skuId)
    }
    // 路径字典
    const pathmap = getPathMap(props.goods.skus)
    // 初始化禁用状态
    changebtstatu(props.goods.specs, pathmap)

    const changeselected = (val, one) => {
      if (one && one.disabled) return
      if (val.selected === one.name) {
        val.selected = null
      } else {
        val.selected = one.name
      }
      changebtstatu(props.goods.specs, pathmap)
      // 将你选择的sku信息通知父组件{skuId,price,oldPrice,inventory,specsText}
      const validselection = getcurrentsku(props.goods.specs).filter((v) => v)
      // 判断是否每个规格都选了
      if (validselection.length === props.goods.specs.length) {
        const skuIds = pathmap[validselection.join(spliter)]
        const sku = props.goods.skus.find((item) => item.id === skuIds[0])
        emit('change', {
          skuId: sku.id,
          price: sku.price,
          oldPrice: sku.oldPrice,
          inventory: sku.inventory,
          // 属性名：属性值 属性名1：属性值1 ... 这样的字符串
          // reduce方法：两个参数，第一个是回调函数，传进去的参数的第一个参数是上一次的值，第二个是当前便利的值
          // 方法的第二个参数是初始值
          specsText: sku.specs
            .reduce((p, c) => `${p} ${c.name}：${c.valueName}`, '')
            .trim()
        })
      } else {
        // 若信息不完整，父组件会判断，然后不能加入购物车
        emit('change', {})
      }
    }
    return { changeselected }
  }
}
</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
